"""nUR MCP Server统一异常处理模块

此模块定义了所有自定义异常类和通用的异常处理函数，用于在整个应用程序中
提供一致的错误处理机制。
"""

import logging
import traceback
from typing import Optional, Dict, Any

# 获取日志记录器
logger = logging.getLogger(__name__)


class NURMCPException(Exception):
    """nUR MCP Server的基础异常类
    
    所有自定义异常都应继承自此类，以确保一致的错误处理。
    """
    def __init__(self, message: str, error_code: str = "UNKNOWN_ERROR", 
                 details: Optional[Dict[str, Any]] = None):
        """初始化异常对象
        
        Args:
            message (str): 错误消息
            error_code (str): 错误代码，用于分类错误类型
            details (dict, optional): 错误详情字典，包含额外信息
        """
        self.message = message
        self.error_code = error_code
        self.details = details or {}
        self.traceback = traceback.format_exc()
        
        super().__init__(f"[{error_code}] {message}")


class ConnectionException(NURMCPException):
    """连接相关异常
    
    用于处理与机器人或网络连接相关的错误。
    """
    def __init__(self, message: str, host: str = "", 
                 port: int = 0, details: Optional[Dict[str, Any]] = None):
        """初始化连接异常
        
        Args:
            message (str): 错误消息
            host (str): 连接的主机地址
            port (int): 连接的端口号
            details (dict, optional): 额外的错误详情
        """
        error_details = {"host": host, "port": port}
        if details:
            error_details.update(details)
            
        super().__init__(message, "CONNECTION_ERROR", error_details)


class RobotCommandException(NURMCPException):
    """机器人命令执行异常
    
    用于处理发送给机器人的命令执行失败情况。
    """
    def __init__(self, message: str, command: str = "", 
                 args: Optional[Dict[str, Any]] = None, 
                 details: Optional[Dict[str, Any]] = None):
        """初始化命令执行异常
        
        Args:
            message (str): 错误消息
            command (str): 执行失败的命令名称
            args (dict, optional): 命令的参数
            details (dict, optional): 额外的错误详情
        """
        error_details = {"command": command}
        if args:
            error_details["args"] = args
        if details:
            error_details.update(details)
            
        super().__init__(message, "ROBOT_COMMAND_ERROR", error_details)


class MotionException(NURMCPException):
    """机器人运动控制异常
    
    用于处理机器人运动相关的错误，如运动超时、碰撞等。
    """
    def __init__(self, message: str, motion_type: str = "", 
                 target: Optional[list] = None, 
                 details: Optional[Dict[str, Any]] = None):
        """初始化运动控制异常
        
        Args:
            message (str): 错误消息
            motion_type (str): 运动类型（如"movej", "movel"等）
            target (list, optional): 目标位置
            details (dict, optional): 额外的错误详情
        """
        error_details = {"motion_type": motion_type}
        if target:
            error_details["target"] = target
        if details:
            error_details.update(details)
            
        super().__init__(message, "MOTION_ERROR", error_details)


class ValidationException(NURMCPException):
    """数据验证异常
    
    用于处理输入参数验证失败的情况。
    """
    def __init__(self, message: str, param_name: str = "", 
                 param_value: Any = None, 
                 details: Optional[Dict[str, Any]] = None):
        """初始化数据验证异常
        
        Args:
            message (str): 错误消息
            param_name (str): 验证失败的参数名称
            param_value: 验证失败的参数值
            details (dict, optional): 额外的错误详情
        """
        error_details = {"param_name": param_name, "param_value": param_value}
        if details:
            error_details.update(details)
            
        super().__init__(message, "VALIDATION_ERROR", error_details)


def handle_exception(exception: Exception) -> Dict[str, Any]:
    """统一的异常处理函数
    
    处理所有类型的异常，返回标准化的错误响应。
    
    Args:
        exception (Exception): 捕获的异常对象
    
    Returns:
        dict: 标准化的错误响应字典，包含错误代码、消息和详情
    """
    # 记录完整的异常堆栈
    logger.error(f"捕获到异常: {str(exception)}")
    logger.debug(f"异常堆栈: {traceback.format_exc()}")
    
    # 根据异常类型构建错误响应
    if isinstance(exception, NURMCPException):
        # 自定义异常，使用其提供的信息
        error_response = {
            "error_code": exception.error_code,
            "message": exception.message,
            "details": exception.details
        }
    else:
        # 标准异常，构建通用响应
        error_type = exception.__class__.__name__
        error_response = {
            "error_code": f"{error_type.upper()}",
            "message": str(exception),
            "details": {"exception_type": error_type}
        }
    
    # 根据错误类型添加额外信息
    if isinstance(exception, ConnectionError):
        error_response["error_code"] = "CONNECTION_ERROR"
    elif isinstance(exception, TimeoutError):
        error_response["error_code"] = "TIMEOUT_ERROR"
    elif isinstance(exception, ValueError):
        error_response["error_code"] = "VALUE_ERROR"
    elif isinstance(exception, KeyError):
        error_response["error_code"] = "KEY_ERROR"
    elif isinstance(exception, AttributeError):
        error_response["error_code"] = "ATTRIBUTE_ERROR"
    
    return error_response


def create_error_response(exception: Exception) -> str:
    """创建标准化的JSON错误响应字符串
    
    处理异常并返回格式化的JSON错误响应。
    
    Args:
        exception (Exception): 捕获的异常对象
    
    Returns:
        str: 格式化的JSON错误响应字符串
    """
    import json
    error_dict = handle_exception(exception)
    return json.dumps({
        "status": "error",
        "error": error_dict
    }, ensure_ascii=False, indent=2)


def exception_handler(func):
    """异常处理装饰器
    
    为函数添加异常捕获和处理功能，返回标准化的错误响应。
    
    Args:
        func: 要装饰的函数
    
    Returns:
        func: 装饰后的函数
    """
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            return create_error_response(e)
    return wrapper


def motion_exception_handler(func):
    """运动控制异常处理装饰器
    
    专为运动控制相关函数设计的异常处理装饰器，提供更具体的错误处理。
    
    Args:
        func: 要装饰的函数
    
    Returns:
        func: 装饰后的函数
    """
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except TimeoutError as e:
            # 处理超时错误
            logger.error(f"运动控制超时: {str(e)}")
            return create_error_response(MotionException(
                str(e),
                motion_type=func.__name__,
                details={"args": args, "kwargs": kwargs}
            ))
        except ConnectionError as e:
            # 处理连接错误
            logger.error(f"运动控制连接错误: {str(e)}")
            return create_error_response(MotionException(
                f"机器人连接中断: {str(e)}",
                motion_type=func.__name__
            ))
        except Exception as e:
            # 处理其他错误
            logger.error(f"运动控制发生错误: {str(e)}")
            return create_error_response(e)
    return wrapper